package com.yequan.datastructure.base.link;

import com.yequan.exception.IllegalArgumentException;

/**
 * 单链表
 *
 * @author : Administrator
 * @date : 2019/12/10
 */
public class SingleLink {

    private Node head = null;

    /**
     * 当前链表的长度
     */
    private int length;

    /**
     * 添加一个节点
     * 分析:
     * 当头结点为空时,表示链表为空,则新增的节点为头结点
     * 当头结点不为空时,新增节点在链表最后添加
     *
     * @param data
     */
    public void addNode(int data) {
        Node newNode = new Node(data);
        if (null == head) {
            head = newNode;
            length++;
            return;
        }
        /**
         * 从头结点开始遍历,直到尾节点,即temp.next=null
         */
        Node temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = newNode;
        length++;
    }

    /**
     * 根据位置删除一个节点
     * 分析:
     * 如果头结点为空,表示为空链表,无效操作
     * 如果链表长度为1,则表示只有一个节点即为头结点,删除头结点
     *
     * @param index
     * @return
     */
    public boolean deleteNode(int index) {
        if (index < 0 || index > length - 1) {
            throw new IllegalArgumentException("越界");
        }
        if (index == 0) {
            head = head.next;
            length--;
            return true;
        }
        Node preNode = head;
        Node currentNode = head.next;
        int i = 0;
        while (currentNode != null) {
            i++;
            if (i == index) {
                preNode.next = currentNode.next;
                length--;
                return true;
            }
            preNode = currentNode;
            currentNode = currentNode.next;
        }
        return false;
    }

    /**
     * 删除指定节点
     * 分析:
     * 删除指定节点,只要将指定节点的数据域等于下一个节点的数据,指针域等于下一个指针的指针
     *
     * @param node
     * @return
     */
    public boolean deleteNode(Node node) {
        if (null == node || node.next == null) {
            return false;
        }
        Node temp = node.next;
        node.data = temp.data;
        node.next = temp.next;
        length--;
        return true;
    }

    /**
     * 根据位置获取节点
     *
     * @param index
     * @return
     */
    public Node getNode(int index) {
        if (index < 0 || index > length - 1) {
            throw new IllegalArgumentException("越界");
        }
        if (index == 0) {
            return head;
        }
        int i = 0;
        Node currentNode = head.next;
        while (null != currentNode) {
            i++;
            if (i == index) {
                return currentNode;
            }
            currentNode = currentNode.next;
        }
        return null;
    }

    /**
     * 链表当前长度
     *
     * @return
     */
    public int size() {
        return length;
    }

    /**
     * 打印当前链表
     */
    public void printLink() {
        Node temp = head;
        while (null != temp) {
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
    }

    public static void main(String[] args) {
        SingleLink singleLink = new SingleLink();
        for (int i = 1; i <= 10; i++) {
            singleLink.addNode(i);
        }
        singleLink.printLink();

        System.out.println();

        Node node = singleLink.getNode(0);
        singleLink.deleteNode(node.next);
        singleLink.printLink();

        System.out.println();

        System.out.println(singleLink.length);
        System.out.println("--------------------");
        singleLink.deleteNode(2);
        singleLink.printLink();

        System.out.println();

        System.out.println(singleLink.length);
    }

}
